package eu.szemraj.net.remoting.amfLite {
    import eu.szemraj.logging.Log;    
    import eu.szemraj.net.ServiceErrorEvent;    

    import flash.events.ErrorEvent;    
    import flash.events.AsyncErrorEvent;    
    import flash.events.SecurityErrorEvent;    
    import flash.events.IOErrorEvent;    
    import flash.events.NetStatusEvent;    

    import eu.szemraj.net.remoting.IAMFService;    
    import eu.szemraj.net.services.AbstractService;        import eu.szemraj.net.remoting.ServiceEvent;   

    import flash.net.Responder;   

    import eu.szemraj.net.Connection;

    public class AMFLiteService extends AbstractService implements IAMFService {

        private var _gatewayURL:String;
        private var _connection:Connection;
        protected var result:Object = null;

        public function AMFLiteService( serviceName:String, gatewayURL:String, objectEncoding:int = 3) {
      	
            super( serviceName );
            _connection = new Connection( objectEncoding );
            _connection.addEventListener( NetStatusEvent.NET_STATUS, netStatusEventHandler );
            _connection.addEventListener( ErrorEvent.ERROR, dispatchErrorEvent );            _connection.addEventListener( IOErrorEvent.IO_ERROR, dispatchErrorEvent );
            _connection.addEventListener( SecurityErrorEvent.SECURITY_ERROR, dispatchErrorEvent );
            _connection.addEventListener( AsyncErrorEvent.ASYNC_ERROR, dispatchErrorEvent );
            if( gatewayURL ) connect( gatewayURL );
        }

        override public function dispose():void {
        	
            super.dispose( );
            _connection.close( );
            _connection.removeEventListener( NetStatusEvent.NET_STATUS, netStatusEventHandler );
            _connection.removeEventListener( ErrorEvent.ERROR, dispatchErrorEvent );
            _connection.removeEventListener( IOErrorEvent.IO_ERROR, dispatchErrorEvent );
            _connection.removeEventListener( SecurityErrorEvent.SECURITY_ERROR, dispatchErrorEvent );
            _connection.removeEventListener( AsyncErrorEvent.ASYNC_ERROR, dispatchErrorEvent );
            _connection = null;
        }
        public function trigger( request:AMFLiteRequest ):void {
        	
            call.apply( this, request.getRequestArray( ) );
        }

        public function connect( gatewayURL:String ):void {
      	
            _gatewayURL = gatewayURL;
            _connection.connect( gatewayURL );
        }

        public function call( functionName:String, ...params ):void {
      
            var responder:Responder = new Responder( onResult, onStatus );	
            var callParams:Array = [serviceIdentifier + "." + functionName, responder];
            for each( var ob:* in params ) {
      		
                callParams.push( ob );	
            }
            _connection.call.apply( null, callParams );
        }

        protected function onResult( result:Object ):void {
      	
            this.result = result; 
            dispatchEvent( new ServiceEvent( ServiceEvent.RESULT, result ) );
        }

        protected function onStatus( status:Object ):void {
      	
            dispatchEvent( new ServiceEvent( ServiceEvent.STATUS, null, status ) );
        }

        protected function netStatusEventHandler(event:NetStatusEvent):void {
        	
        	 if( event.info["level"] == "error") {
        	 	
        	 	dispatchErrorEvent( new ErrorEvent( event.info["code"] )  );
            }
        }
        
        protected function get serviceIdentifier():String {
        	
        	return "SERVICE";
        	
        }

        private function dispatchErrorEvent(event:ErrorEvent ):void {
         	
            dispatchEvent( new ServiceErrorEvent( ServiceErrorEvent.CONNECTION_ERROR, event ) );
        }
        
        
    }
}
